package com.cavy.platform.server.domain.job;

import com.cavy.platform.server.BeansProvider;
import com.cavy.platform.server.domain.message.JobRunningMessage;
import com.cavy.platform.server.mapper.JobActionMapper;
import com.cavy.platform.server.repository.JobRepository;
import com.cavy.platform.server.service.JobSubscribe;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.Objects;

@Data
@Slf4j
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "className", defaultImpl = PendingJob.class)
@JsonSubTypes({
        @JsonSubTypes.Type(value = EndJob.class),
        @JsonSubTypes.Type(value = ErrorJob.class),
        @JsonSubTypes.Type(value = TimeoutErrorJob.class),
        @JsonSubTypes.Type(value = RunningJob.class),
        @JsonSubTypes.Type(value = PendingJob.class)
})
public abstract class AbstractJobAction implements JobAction {
    protected Job job;

    public AbstractJobAction() {
    }

    public AbstractJobAction(Job job) {
        this.job = job;
        initJobStatus();
    }

    /**
     * 加载
     *
     * @param message 消息中携带有job标识
     * @return 具体的实例, 但是对于不同类型的实例, 具体属性需要自己赋值
     */
    @Override
    public JobAction load(JobRunningMessage message) {
        JobRepository bean = BeansProvider.getBean(JobRepository.class);
        assert bean != null;
        JobAction load = bean.load(message.getWorkspaceName(), message.getProjectName(), message.getPipelineName(),
                message.getNumber());
        JobActionMapper.INSTANCE.convert(load, this);
        initJobStatus();
        return load;
    }

    /**
     * 保存
     */
    protected void save(JobAction action) {
        Objects.requireNonNull(BeansProvider.getBean(JobRepository.class)).save(action);
    }

    protected JobStage getStage(String stageName) {
        for (JobStage jobStage : job.getJobStageList()) {
            if (jobStage.getName().equals(stageName)) {
                return jobStage;
            }
        }
        return null;
    }

    protected JobContainer getContainer(String stageName, int index) {
        JobStage stage = getStage(stageName);
        if (stage != null) {
            return stage.getContainerList().get(index);
        }
        return null;
    }

    protected JobSubscribe getSubscribe() {
        return BeansProvider.getBean(JobSubscribe.class);
    }

    protected void sendJob() {
        JobSubscribe subscribe = getSubscribe();
        subscribe.send(job, this);
    }

    protected void removeSubscribe() {
        JobSubscribe subscribe = getSubscribe();
        if (job.isEnd()) {
            subscribe.closeSession(job);
        }
    }
}
